msmCoefTable = function(msmModel, checkMinor=0) {
 
  msmModel_res = paste0(deparse(substitute(msmModel)), "_res")
  
  oneres = get(msmModel_res)
  
  allvars = c("minor", "post45", "AOS30", "AOS60", "AOS90", "AOS60LL", 
              "AOA", "apropdiff",
              "issues", "contig", "cincP", 
              "doeWinLose", "doeWinLose_scale", 
              "polBinA", "nuk", "nBellig", "anyDipEnemy", 
              "outAllies", "outP5Allies", "outKeyAllies", "keyAllies",
              "logBattles")
  allvarsn = c("Minor power war", "Post-1945", "Recent imbalance", "Recent imbalance", "Recent imbalance", "Recent imbalance", 
               "Overall imbalance", "Inconsistency",
               "Issue salience", "Contiguity", "CINC ratio",
               "DOE score", "DOE score",
               "Democratic initiator", "Nuclear", "Number of states", "Opp. dip. representation", 
               "Outside allies", "Outside P5 allies", "Outside major allies", "Major allies",
               "Completed battles")
  
  starList = list()
  for (i in 1:length(allvars)) {
    # What's the variable?
    onevar = allvars[i]
    onevarn = allvarsn[i]
    varres = oneres %>% filter(vars==onevar)
    
    # Move on if the variable doesn't exist
    if (nrow(varres)==0) {next}
    
    # Reorder the transitions to be consistent with the book
    varres$trans = factor(varres$trans, levels=c("State 1 - State 2", "State 2 - State 1",
                                                 "State 1 - State 3", "State 2 - State 3"))
    varres = varres %>% arrange(trans)
    
    # Get the estimates
    varests = varres$est
    varlows = varres$lower
    varups = varres$upper
    
    # Use 95% bounds to calculate the standard error
    varses = (varups - varests)/qnorm(0.975)
    
    # Check statistical significance
    stars = ifelse(abs(varests) - qnorm(0.995)*varses > 0, "^{***}", 
                   ifelse(abs(varests) - qnorm(0.975)*varses > 0, "^{**}",
                          ifelse(abs(varests) - qnorm(0.95)*varses > 0, "^{*}", "")))
    
    # Get the hazard rates
    hazrates = exp(varests)
    hazrates_disp = round(hazrates, 3)
    hazrates_disp = sprintf("%.3f", hazrates_disp)  
    hazrates_disp = paste0("[", hazrates_disp, "]")
    
    # Create numbers to display 
    varests_disp = round(varests, 3)
    varests_disp = sprintf("%.3f", varests_disp)
    varests_disp = as.character(paste0(varests_disp, stars))
    varses_disp = round(varses, 3)
    varses_disp = sprintf("%.3f", varses_disp)  
    varses_disp = paste0("(", varses_disp, ")")
    
    vardisp = data.frame(rbind(varests_disp, varses_disp, hazrates_disp))
    vardisp = data.frame(var=c(onevarn, "", ""), vardisp)
    
    starList[[i]] = vardisp
  }
  
  thestars = rbindlist(starList)
  
  # Get -2*LL
  m2LL = round(msmModel["minus2loglik"][[1]], 3)
  m2LL = data.frame(V1="$-2 \\times$ log-likelihood", V2=m2LL, V3="", V4="", V5="")
  thestars = rbind(thestars, m2LL, use.names=F)
  
  # Add labels
  if (checkMinor==1) {
    names(thestars) = c("", "Start Int. Neg.", "End Int. Neg.", "Start Ext. Neg.", "End Ext. Neg")
  } else {
    names(thestars) = c("", "Start Neg.", "End Neg.", "Vict./Def.", "Neg. Settle")
  }
  
  starTable = xtable(thestars)
  print(starTable, include.rownames=F, sanitize.text.function=identity,
        hline.after=(nrow(starTable)-1))
  
}

